vue-router是一個很好用的工具,因為過去在換頁通常會透過後端處理。而目前為了減少讀取時間,目前大多都採用SPA(單頁式應用)來製作,如前端框架,而在切換同時我們還需要控制網址,所以才會有router的出現,vue-router,當我們切換畫面時候也不需向後端發出請求。
安裝:
此處我們是直接使用vue ui進行安裝,如果不使用ui介面的話,透過npm安裝即可。
npm install vue-router
或是透過cdn直接引入。
<script src="/path/to/vue.js"></script>
<script src="/path/to/vue-router.js"></script>
進入畫面後發現,多出兩個分別為Home、About的頁面,當我們做切換時,網址也會做變化,而在網址的#
作用是用來防止換頁,因為目前我們沒有跟任何後端做搭配的動作。
而回到我們檔案觀看,可發現main.js多出一個router,並綁至app。
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
且我們也可發現多出一個名為router的資料夾,並且有一個為index.js的檔案,而作用是用來定義我們專案有多少路徑的部分
,而可看到我們目前有個根目錄Home,一個目錄About,而每一個路徑也會對應到對應的component,而我們在此也增加一個router名為jojo。
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
// 使用了 Vue.use( VueRouter ),會在 Vue 中增加<router-view/> 與 <router-link/> 這兩個組件
Vue.use(VueRouter)
// 定義我們專案有多少路徑的部分
const routes = [{
// 每一個路徑也會對應到對應的component,
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
},
{
path: '/jojo',
name: 'Jojo',
component: () => import( /* webpackChunkName: "about" */ '../views/jojo.vue')
}
]
const router = new VueRouter({
routes
})
export default router
我們回到App.vue,可以發現template多出了一個router-link的組件及router-view的組件,而router-link用來切換router
,router-view用來顯示我們與router綁定的component
。
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/jojo">Jojo</router-link>
</div>
<router-view/>
</div>
</template>
而此時我們切換到畫面,發現我們所新增的路由已經在畫面上,並且切換到那個頁面,網誌及畫面也會跟著做變化,在vue Devtools也能發現總共有三個router link專門切換router,router view專門顯示我們的router component。
而此時,我們來看看network的部分,重整後發現app.js,about.js都沒有載入進來(狀態為304),而當我們點擊about切換頁面後,發現about.js已經載入進來,並且狀態變為200。
而這也跟我們在index.js中,也就是定義我們專案有多少路徑的部分,在定義我們router的組件時做法不同的差異,而上圖為我們採用router lazyload
做法,直接透過import去引入他,依照router將code分割,優點
在於當我們進入其頁面,才會真正把其頁面的資料載入進來,可以節省一開始的讀取時間
,而壞處就是會多一次讀取
。
component: () => import( /* webpackChunkName: "about" */ '../views/jojo.vue')
而如果我們希望在切換頁面時,能夠將其router改變顏色,傳統一般都是套用class去active修改,而vue有提供兩個class分別為.router-link-active,.router-link-exact-active,而router-link-active指經過的目錄(少用)
,.router-link-exact-active指當前頁面
,所以當我們點擊到jojo或about頁面時,皆會顯示棕色,而Home一直顯示紅色。
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
.router-link-active{
color:red;
}
.router-link-exact-active{
color:brown;
}
</style>
今天如果我想在jojo這個路徑的頁面下在增添其他路徑,達到巢狀路由的架構,那麼該怎麼做呢?
首先我們在index.js的部分,也就是定義路徑的地方加上我們所要增添的路徑,由於我們新增的路徑是要增添在jojo路徑的頁面下,所以我們使用一個屬性children子路由,表示在這層路徑下還要再開一層路徑
,而path,name,component一樣比照一般寫法,要注意的是子路徑path的部分前面不用在加'/'
,如/info(X),info(O)
// 定義我們專案有多少路徑的部分
const routes = [{
...
{
path: '/jojo',
name: 'Jojo',
component: () => import( /* webpackChunkName: "jojo" */ '../views/jojo.vue'),
// 子路由,表示在這層路徑下還要再開一層路徑
children: [{
// 子路徑路由不用再加/,否則會回到根目錄
path: "info",
name: "jojo-info",
component: () => import( /* webpackChunkName: "jojo-info" */ '../views/info.vue')
},
{
path: "youtube",
name: "jojo-youtube",
component: () => import( /* webpackChunkName: "jojo-youtube" */ '../views/youtube.vue')
},
]
},
]
接著再views的資料夾下創建info,youtube子路徑的頁面,並增添我們想顯示的內容,再來我們回到我們的jojo.vue下,注意,Component的最外面只能有一層DOM(此處為div)
,而我們在底下寫入我們的路徑,而第一個這種寫法,如果資料好幾層,網址越來越長,用to="/.../..."的方法不方便。
<div>
<router-link> to="/jojo/info">info </router-link>
<router-link> to="/jojo/youtube">youtube </router-link>
</div>
所以可以改綁定寫法,由於我們在path部分都有加上name,所以可以直接綁其路由的name=> :to="{name}"
。
<template>
<div>
Component的最外面只能有一層DOM(此處為div)
<h1>Jojo router</h1>
<div>
<router-link :to="{name:'jojo-info'}">info</router-link>
<router-link :to="{name:'jojo-youtube'}">youtube</router-link>
</div>
<router-view/>
</div>
</template>
完成如下。